package com.example.design_pattern.proxy;

//jdk的代理模式有了解过吗？(一共需要5个基本构建：1个父接口、2个被代理类、1个代理类、1个测试类)
//
//常见的有静态代理和动态代理。
//所谓静态代理，就是代理类王婆是实现我们自己定义好的类。
//所谓动态代理，就是我们实现并没有定义好代理类王婆，而是我们通过Proxy.newProxyInstance(xx, xx, xx)这句话动态生成的。
//
//静态代理：看例子就秒懂了。
// 测试类
public class ProxyTest02 {
    public static void main(String[] args) {

        // 创建被代理对象1，金莲对象
        JinLian jl = new JinLian();
        // 创建被代理对象2，阎婆惜对象
        YanPoXi ypx = new YanPoXi();

        // 创建代理金莲的代理对象1，王婆1
        WangPo wp1 = new WangPo(jl);
        // 创建代理阎婆惜的代理对象2，王婆2
        WangPo wp2 = new WangPo(ypx);

        // 代理对象调用自己的方法，就能调用到被代理对象的同名方法。
        wp1.happy();
        wp2.happy();
    }
}

// 总得自己弄个父接口，不然到时候WangPo类里面FindHappy fh;这句多态不太好写，只能写Object fh了。因为我总得用个公共父类或者父接口来描述到时候传进来的被代理对象的数据类型。
interface FindHappy {
    void happy();
}

// 被代理类一
class YanPoXi implements FindHappy {
    @Override
    public void happy() {
        System.out.println("阎婆惜在happy....");
    }
}

// 被代理类二
class JinLian implements FindHappy {
    @Override
    public void happy() {
        System.out.println("金莲在happy...");
    }
}


//代理类。
//代理类主要实现一些要被增强在代理类上面的逻辑。
class WangPo implements FindHappy {
    // 这个用来保存金莲和阎婆惜的，也就是，被代理类的实例对象。
    FindHappy fh;

    // 保存通过构造函数传进来的被代理实例对象。为什么要用FindHappy类型接收呢，其实就是多态。没搞个FindHappy接口，以好把yanpoxi和jinlian都能笼阔在一个公共的父类，这样才能统一处理，不然，fh用什么类型，只能再往上找找到Object了，总之不能动态地变化fh的类型吧。
    public WangPo(FindHappy fh) {
        this.fh = fh;
    }

    //这个就是我们的王婆的happy()方法，是加强之后的。
    @Override
    public void happy() {
        System.out.println("王婆约好人,开好房间..."); //加强功能之一
        // 被代理对象.happy();
        fh.happy();
        System.out.println("王婆打扫战场..."); //加强功能之二
    }
}